using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
	#region Constants
    private const float MAX_FIRE_TIME = 0.2f;
	#endregion
	
    #region Fields
    public float PlayerSpeed;
    public GameObject ProjectilePrefab;
	public GameObject ExplosionPrefab;
	
	// FSM
	private enum State
	{
		Playing,
		Explosion,
		Invincible
	}
	private State state = State.Playing;
	
	// Members
	private float shipInvisibleTime = 1.5f;
	private float shipMoveOnToScreenSpeed = 5f;
	private float blinkRate = 0.1f;
	private int numberOfTimesToBlink = 10;
	private int blinkCount = 0;
    private float fireTime = 0f;
    #endregion
    

    #region Static Vars
    public static int Score = 0;
    public static int Lifes = 3;
    #endregion
   

    #region Properties
    private Transform mTransform;
    #endregion
   
	
	//----------- GENERAL METHODS -------//
	// Start is called when the object is created
	void Start()
	{
		mTransform = transform;
        fireTime = MAX_FIRE_TIME;
	}
	
	// Update is called once per frame
	void Update ()
    {
		// Check the current state of the player
		switch(state)
		{
			case State.Playing:
			case State.Invincible:
				// Get the amount to move.
				float amntToMove = Input.GetAxisRaw("Horizontal") * PlayerSpeed * Time.deltaTime;
                mTransform.Translate(Vector3.right * amntToMove);

                // Move the player accordingly to the mouse down
                if (Input.GetMouseButton(0))
                {
                    float amntToMoveX = Input.GetAxisRaw("Mouse X") * PlayerSpeed * Time.deltaTime;
                    float amntToMoveY = Input.GetAxisRaw("Mouse Y") * PlayerSpeed * Time.deltaTime;
                    mTransform.Translate(Vector3.right * amntToMoveX);
                    mTransform.Translate(Vector3.up * amntToMoveY);
                }
               
                 if (Input.touchCount > 0 &&  Input.GetTouch(0).phase == TouchPhase.Moved) 
                 {
                     Debug.Log("Touch");
                     float speed = 1.0f;
                    // Get movement of the finger since last frame
                    Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
        
                    // Move object across XY plane
                    transform.Translate (-touchDeltaPosition.x * speed, 
                                -touchDeltaPosition.y * speed, 0);
                }
				
				// Wrap. If the player leave the screen by any of the edges, it will appear
				// over the opposite one.
				if(Mathf.Abs(mTransform.position.x) > 7.5f)
					mTransform.position = new Vector3((mTransform.position.x * -1), mTransform.position.y, mTransform.position.z);
				
				// Check if the player has pressed the spacebar
                //if(Input.GetKeyDown("space"))
                //{
                //    // Fire a projectile
                //    Vector3 position = mTransform.position + (Vector3.up * (collider.bounds.size.y/2));
                //    Instantiate(ProjectilePrefab, position, Quaternion.identity);
                //}
                if (fireTime > 0)
                {
                    fireTime = Mathf.Max(0f, fireTime - Time.deltaTime);
                    if (fireTime <= 0)
                    {
                        fireTime = MAX_FIRE_TIME;

                        // Fire a projectile
                        Vector3 position = mTransform.position + (Vector3.up * (collider.bounds.size.y/2));
                        Instantiate(ProjectilePrefab, position, Quaternion.identity);
                    }
                }
			break;
		}
	}
	
	 // Override the onTrigger event
    void OnTriggerEnter(Collider otherObject)
    {
		switch(state)
		{
			case State.Playing:
			 	if (otherObject.tag == "enemy")
		        {
					// Decrease the player lifes
					Player.Lifes--;
					
		            // Refresh the enemy position
		            Enemy enemy = (Enemy)otherObject.gameObject.GetComponent("Enemy");
		            enemy.SePositionAndSpeed();
					
					StartCoroutine(DestroyShip());
		        }
			break;
		}
    }

   
	
	IEnumerator DestroyShip()
	{
		// Change the state to explosion
		state = State.Explosion;
		
		// Instantiate the explosion
		Instantiate(ExplosionPrefab, mTransform.position, mTransform.rotation);
		
		// Hide the player
		gameObject.renderer.enabled = false;
		
		// Position the ship centered but out of the screen
		transform.position = new Vector3(0f, -6f, transform.position.z);
		yield return new WaitForSeconds(shipInvisibleTime);
		
		if(Player.Lifes <= 0)
		{
			// Change to the Lose Screen
			Application.LoadLevel(GameConstants.LOSE_SCREEN);
		}
		else
		{
			// Make the player visible
			gameObject.renderer.enabled = true;
			
			while(transform.position.y < -4.3f)
			{
				// Move the ship up
				float amntToMove = shipMoveOnToScreenSpeed * Time.deltaTime;
				mTransform.position = new Vector3(0f, mTransform.position.y + amntToMove, mTransform.position.z);
				
				// With this instruction, the yield, we interrupt the function flow until the next frame
				yield return 0;
			}
			
			// Change the state
			state = State.Invincible;
			
			// Make the player blink
			while (blinkCount < numberOfTimesToBlink)
			{
				gameObject.renderer.enabled = !gameObject.renderer.enabled;
				
				// Increase the blinking count if needed
				if (gameObject.renderer.enabled)
				{
					blinkCount++;
				}
				
				// With this instruction, the yield, we interrupt the function flow until the blink rate is finished
				yield return new WaitForSeconds(blinkRate);
			}
			
			// Reset the blink count
			blinkCount = 0;
			
			// Change the state
			state = State.Playing;
		}
	}
}
